#if !defined(ximera_xml_xmlnode_hpp)
#define ximera_xml_xmlnode_hpp

// -----------------------------------------------------------

#include <ximera/types.hpp>
#include <ximera/enum.hpp>
#include <ximera/common/sharedptr.hpp>
#include <ximera/exception.hpp>

#include <vector>

namespace ximera { namespace xml
{
    XIMERA_DECLARE_EXCEPTION(XmlException, L"Error parsing XML");

    XIMERA_ENUM(XmlNodeType)
        Unknown,
        Document,
        Element,
        Comment,
        Text,
        Declaration
    XIMERA_ENUM_END(XmlNodeType)

    class XIMERA_API XmlNode
    {
    public:
        typedef std::vector<SharedPtr<XmlNode> > ChildContainer;
        typedef ChildContainer::iterator ChildIterator;
        typedef ChildContainer::const_iterator ChildConstIterator;

    public:
        XmlNode();
        virtual ~XmlNode();

        virtual XmlNodeType type() const { return XmlNodeType::Unknown; }

        String const& value() const;
        void value(String const& value);

        bool hasChildren() const;

        ChildIterator childBegin() { return _children.begin(); }
        ChildConstIterator childBegin() const { return _children.begin(); }

        ChildIterator childEnd() { return _children.end(); }
        ChildConstIterator childEnd() const { return _children.end(); }
        
        void insert(XmlNode* node);
        void remove(XmlNode* node);
        void removeAll();

        XmlNode* parent() const;

        XmlNode* firstChild() const;
        XmlNode* firstChild(String const& value) const;
        
        XmlNode* lastChild() const;
        XmlNode* lastChild(String const& value) const;

        XmlNode* previousSibling() const;
        XmlNode* nextSibling() const;

    private:
        friend class XmlDocument;

    protected:
        ChildContainer _children;
        XmlNode* _parent;
        XmlNode* _prev;
        XmlNode* _next;

        String _value;
    };
}}

// -----------------------------------------------------------

#endif